[bits 32]

global asm_hello_world
global asm_lidt
global asm_unhandled_interrupt
global asm_halt

ASM_UNHANDLED_INTERRUPT_INFO db 'Unhandled interrupt happened, halt...'
                             db 0
ASM_IDTR dw 0
         dd 0

; void asm_unhandled_interrupt()
asm_unhandled_interrupt:
    cli
;    mov esi, ASM_UNHANDLED_INTERRUPT_INFO
;    xor ebx, ebx
;    mov ah, 0x03
;.output_information:
;    cmp byte[esi], 0
;    je .end
;    mov al, byte[esi]
;    mov word[gs:bx], ax
;    inc esi
;    add ebx, 2
;    jmp .output_information
.end:

;清屏
  mov edi, 0xB8000 ; 显存的起始地址
  mov ecx, 80*25 ; 屏幕总共有 80*25 个字符
  xor eax, eax ; 将要填充的字符和属性（这里用 0 表示空白字符和黑色背景）
  mov ah, 0x07 ; 白底黑字
  rep stosw ; 使用 stosw 指令填充显存
;自定义字符弹射（32位
mov ecx, 0
mov dh, 2
mov dl, 0
mov ah, 0x07
mov al, 48



loop:
  call change
  call print_al
  call symmetry
  call delay
  jmp loop

  jmp $

; 函数功能：改变数字和颜色
change:
  add ah, 3
  cmp al, '0'
  jl  set_0
  cmp al, '9'
  jge set_0

  inc al
  ret

  set_0:
    mov al, '0'
  ret ; 

; 函数功能：延迟一定时间
delay:
  pushad
  mov ebx, 20000000 ; 设置需要延迟的时钟周期数
  delay_loop:
  dec ebx ; 浪费1个时钟周期
  jnz delay_loop ; 如果还有剩余时钟周期，则继续浪费
  popad
  ret ; 返回调用者

print_al:
  pushad
  mov ebx, 0
  add bl, dh
  imul ebx, ebx, 80
  and edx, 0x000000ff  ;dl列数
  add ebx, edx
  imul ebx, ebx, 2
  mov [gs:ebx], ax
  popad
  ret

symmetry:
  pushad
  sub dh, 24  ;对称位置
  neg dh
  sub dl, 79  
  neg dl
  
  mov ebx, 0  ;打印字符同print_al
  add bl, dh
  imul ebx, ebx, 80
  and edx, 0x000000ff  ;dl
  add ebx, edx
  imul ebx, ebx, 2
  mov [gs:ebx], ax
  popad
  call pos_change;改变位置
  ret
  
pos_change:
  branch1: cmp ecx, 0 ;右下
    jne branch2
    	
    b11: cmp dh, 24  ;行号24
    jne b12
    sub dh, 1
    add dl, 1
    mov ecx, 1 ;右上
    jmp end_1
    
    b12: cmp dl, 79 ;列号79
    jne b13
    sub dl, 1
    add dh, 1
    mov ecx, 3 ;左下
    jmp end_1
    
    b13: ;正常
    add dl, 1
    add dh, 1
    
    end_1:
    
    jmp end_if

  branch2: cmp ecx, 1 ;右上
    jne branch3
    
    b21: cmp dh, 0  ;行号0
    jne b22
    add dh, 1
    add dl, 1
    mov ecx, 0 ;右下
    jmp end_2
    
    b22: cmp dl, 79 ;列号79
    jne b23
    sub dl, 1
    sub dh, 1
    mov ecx, 2 ;左上
    jmp end_2
    
    b23: ;正常
    add dl, 1
    sub dh, 1

    end_2:
    
    jmp end_if

  branch3: cmp ecx, 2 ;左上
    jne branch4

    b31: cmp dh, 0  ;行号0
    jne b32
    add dh, 1
    sub dl, 1
    mov ecx, 3 ;左下
    jmp end_3
    
    b32: cmp dl, 0 ;列号0
    jne b33
    add dl, 1
    sub dh, 1
    mov ecx, 1 ;右上
    jmp end_3
	
    b33: ;正常
    sub dl, 1
    sub dh, 1

    end_3:		

    jmp end_if

  branch4: cmp ecx, 3 ;左下
	
    b41: cmp dh, 24  ;行号24
    jne b42
    sub dh, 1
    sub dl, 1
    mov ecx, 2 ;左上
    jmp end_4

    b42: cmp dl, 0 ;列号0
    jne b43
    add dl, 1
    add dh, 1
    mov ecx, 0 ;右下
    jmp end_4
	
    b43: ;正常
    sub dl, 1
    add dh, 1
			
    end_4:
  end_if:

  ret

    jmp $

; void asm_lidt(uint32 start, uint16 limit)
asm_lidt:
    push ebp
    mov ebp, esp
    push eax

    mov eax, [ebp + 4 * 3]
    mov [ASM_IDTR], ax
    mov eax, [ebp + 4 * 2]
    mov [ASM_IDTR + 2], eax
    lidt [ASM_IDTR]

    pop eax
    pop ebp
    ret

asm_hello_world:
    push eax
    xor eax, eax

    mov ah, 0x03 ;青色
    mov al, 'H'
    mov [gs:2 * 0], ax

    mov al, 'e'
    mov [gs:2 * 1], ax

    mov al, 'l'
    mov [gs:2 * 2], ax

    mov al, 'l'
    mov [gs:2 * 3], ax

    mov al, 'o'
    mov [gs:2 * 4], ax

    mov al, ' '
    mov [gs:2 * 5], ax

    mov al, 'W'
    mov [gs:2 * 6], ax

    mov al, 'o'
    mov [gs:2 * 7], ax

    mov al, 'r'
    mov [gs:2 * 8], ax

    mov al, 'l'
    mov [gs:2 * 9], ax

    mov al, 'd'
    mov [gs:2 * 10], ax

    pop eax
    ret

asm_halt:
    jmp $
